package utils

import data.ScheduleResponseData

fun encodeResponseData(data: ScheduleResponseData): String {
    val charArray = CharArray(getEncodeDataSize(data))
    var offset = charArray.appendStr(0, "scd[")
    offset = charArray.appendIntValue(offset, data.scheduleVersion)
    data.scheduleItems.forEach { item ->
        offset = charArray.appendIntValue(offset, item.id)
        offset = charArray.appendChar(offset, "[".getChar())
        item.turnOnTimeList.forEach { actionTime ->
            offset = charArray.appendIntValue(offset, actionTime)
        }
        offset = charArray.appendStr(offset, "][")
        item.turnOffTimeList.forEach { actionTime ->
            offset = charArray.appendIntValue(offset, actionTime)
        }
        offset = charArray.appendChar(offset, "]".getChar())
    }
    offset = charArray.appendStr(offset, "]itr[")
    offset = charArray.appendIntValue(offset, data.interruptVersion)
    data.interruptItems.forEach {item ->
        offset = charArray.appendIntValue(offset, item.id)
        if (item.action) {
            offset = charArray.appendChar(offset, "+".getChar())
        } else {
            offset = charArray.appendChar(offset, "-".getChar())
        }
    }
    offset = charArray.appendChar(offset, "]".getChar())
    return String(charArray)
}

private fun getEncodeDataSize(data: ScheduleResponseData) : Int {
    var size = 12 // scd + itr + [] + [] + 2 * version
    data.scheduleItems.forEach { item ->
        size += 5 // id + [] + []
        size += item.turnOnTimeList.size
        size += item.turnOffTimeList.size
    }
    size += data.interruptItems.size * 2

    return size
}

private fun CharArray.appendStr(offset: Int, content: String): Int {
    for (i in content.indices) {
        this[offset + i] = content[i]
    }

    return offset + content.length
}

private fun CharArray.appendIntValue(offset: Int, value: Int): Int {
    if (value > 79) {
        throw Exception("The value cannot be greater than 79!")
    }
    this[offset] = Char(48 + value)
    return offset + 1
}

private fun CharArray.appendChar(offset: Int, char: Char): Int {
    this[offset] = char
    return offset + 1
}

private fun String.getChar(): Char {
    return this[0]
}